package mainControls;

import smallTools.SimpleTime;
import smallTools.TimeSlotUtility;
import entities.Course;
import entities.Room;
import entities.Section;

public class Scheduler {
	private TimeSlotUtility m_timeSlotUtility;
	private StaffScheduleChecker m_staffChecker;
	private LectureChecker m_lectureChecker;
	private CoreCourseChecker m_coreCourseChecker;
	private RoomChecker m_roomChecker;

	public Scheduler() {
		m_timeSlotUtility = new TimeSlotUtility();
		m_staffChecker = new StaffScheduleChecker();
		m_lectureChecker = new LectureChecker();
		m_roomChecker = new RoomChecker();
		m_coreCourseChecker = new CoreCourseChecker();
	}

	public void generateSchedule() {
		String[] courseCodeList = Course.getAllCourses();
		for (String courseCode : courseCodeList) {
			Course currentCourse = Course.getCourseByCode(courseCode);

			String[] lectures = currentCourse.getAllLecture();
			for (String lectureId : lectures) {
				allocateTimeSlot(lectureId, currentCourse);
			}

			String[] tutorials = currentCourse.getAllTutorial();
			for (String tutorialId : tutorials) {
				allocateTimeSlot(tutorialId, currentCourse);
			}
		}
	}

	private void allocateTimeSlot(String sectionId, Course courseNow) {
		try {
			Section currentSection = Section.getSectionById(sectionId);
			int duration = currentSection.getSectionDuration();

			boolean sectionScheduled = false;
			SimpleTime currentStartTime = m_timeSlotUtility.getFirstTimeSlot();
			while (sectionScheduled == false) {

				if (passAllCheckers(currentSection, courseNow, currentStartTime))
					sectionScheduled = true;
				else {
					currentStartTime = m_timeSlotUtility
							.getNextTimeSlot(duration);
					if (currentStartTime == null) {
						throw new Exception(
								"Error with section \""
										+ sectionId
										+ "\": Cannot find an appropriate time slot for it ");
					}
				}
			}

			// allocating
			currentSection.setSectionStartTime(currentStartTime);
			String roomId = m_roomChecker.getAllocatedRoomId();
			currentSection.setSectionRoom(roomId);
			Room.getRoomById(roomId).addSection(sectionId);
		} catch (Exception e) {
			System.out.println("Scheduler Null!");
			System.out.println(e.getMessage());
		}
	}

	private boolean passAllCheckers(Section theSection, Course theCourse,
			SimpleTime startTimeCandidate) {
		if (m_staffChecker.check(theSection, startTimeCandidate) == false)
			return false;
		else if (m_lectureChecker.check(theSection, theCourse,
				startTimeCandidate) == false)
			return false;
		else if (m_coreCourseChecker.check(theSection, theCourse,
				startTimeCandidate) == false)
			return false;
		else if (m_roomChecker.check(theSection, startTimeCandidate) == false)
			return false;
		else
			return true;
	}
}
